package com.rwind.schema.controller;

import org.codehaus.janino.ExpressionEvaluator;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class JaninoSpringIntegration implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public Object evaluateExpressionx(String beanName, String expression, Object[] argumentValues) throws Exception {
        ExpressionEvaluator ee = new ExpressionEvaluator();
        ee.setParentClassLoader(this.applicationContext.getClassLoader()); // Use the application context's class loader
        // Define the expression type as the return type of the expression
        Class<?> expressionType = (Class<?>) this.applicationContext.getBean(beanName); // Replace "yourType" with the actual type name
        // Compile the expression
        ee.cook(expression);
        // Evaluate the expression
        return ee.evaluate(argumentValues, expressionType, null);
    }

    /*
    <pre>
    // 准备要评估的表达式
     String expression = "yourExpression"; // 替换为实际的表达式
     Object[] argumentValues = new Object[] {
     }; // 替换为实际的参数
     try{
        // 调用 evaluateExpression 方法
        Class<?> returnType=YourReturnType.class; // 替换为实际的返回类型
    Object result=janinoIntegration.evaluateExpression(expression,argumentValues,returnType);
            // 使用评估的结果进行其他操作
            }catch(Exception e){
            // 处理异常
            }
      </pre>
        */
    public Object evaluateExpression(String expression,String[] parameterNames, Object[] argumentValues, Class<?> returnType) throws Exception {
        ExpressionEvaluator ee = new ExpressionEvaluator();
        ee.setParentClassLoader(this.applicationContext.getClassLoader());
        Class[] paramType = new Class[parameterNames.length] ;
        for (int i = 0; i < parameterNames.length; i++) {
            paramType[i] = argumentValues[i].getClass();
        }
        ee.setParameters(parameterNames,paramType);
        ee.setExpressionType(returnType);
       // ee.setExtendedClass(returnType);
        ee.cook(expression);
        return ee.evaluate(argumentValues);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}